// NewTrainingFramework.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "../Utilities/utilities.h" // if you use STL, please include this line AFTER all other include
#include "Vertex.h"
#include "Shaders.h"
#include <conio.h>
#include "Globals.h"
#include "Camera.h"
#include "Triangle.h"
#include "Line.h"
#include "Cube.h"

GLuint vboId;
Shaders myShaders;
Camera camera;
Vertex* verticesData, *verticesData2, *verticesData3;
Triangle triangle, triangle2;
Line cameraRay;
Matrix* mvpMatrix;
char* imgData;
int width, height, bpp;
Cube* cube;


int Init ( ESContext *esContext )
{
	cube = new Cube;
	glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
	glGenTextures(1, &(triangle.textureID));
	glBindTexture(GL_TEXTURE_2D, triangle.textureID);
	camera.setFOV(Vector3(0, 0, 5), Vector3 (0, 1, 0), Vector3(), 1.0f, Globals::screenWidth / Globals::screenHeight,1, 1000);
	imgData = LoadTGA("Marine.tga", &width, &height, &bpp);
	//load tex
	if (bpp == 24)
		//RGB
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imgData);
	else
		//RGBA
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
	delete[] imgData;
	
	//filter for minification
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	//filter for magnification
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// gen mipmap
	glGenerateMipmap(GL_TEXTURE_2D);
	//

	verticesData = triangle.vertices;
	//triangle data (heap)
	verticesData[0].pos.x =  0.0f;  verticesData[0].pos.y =  0.5f;  verticesData[0].pos.z =  0.0f;
	verticesData[1].pos.x = -0.5f;  verticesData[1].pos.y = -0.5f;  verticesData[1].pos.z =  0.0f;
	verticesData[2].pos.x =  0.5f;  verticesData[2].pos.y = -0.5f;  verticesData[2].pos.z =  0.0f;

	verticesData[0].color.x =  1.0f;  verticesData[0].color.y =  0.0f;  verticesData[0].color.z =  0.0f, verticesData[0].color.w = 1.0f;
	verticesData[1].color.x =  0.0f;  verticesData[1].color.y =  .0f;  verticesData[1].color.z =  0.0f, verticesData[1].color.w = 0.5f;
	verticesData[2].color.x =  0.0f;  verticesData[2].color.y =  0.0f;  verticesData[2].color.z =  1.0f, verticesData[2].color.w = 0.5f;

	
	verticesData[0].uv.x =  0.5f;  verticesData[0].uv.y = 1.0f;
	verticesData[1].uv.x =	0.0f;  verticesData[1].uv.y = 0.0f;
	verticesData[2].uv.x =  1.0f;  verticesData[2].uv.y = 0.0f;

	
	//verticesData2 = triangle2.vertices;
	////triangle2 data (heap)
	//verticesData2[0].pos.x =  0.0f;  verticesData2[0].pos.y =  0.25f;  verticesData2[0].pos.z =  0.5f;
	//verticesData2[1].pos.x = -1.0f;  verticesData2[1].pos.y = 0.0f;  verticesData2[1].pos.z =  0.0f;
	//verticesData2[2].pos.x =  1.0f;  verticesData2[2].pos.y = 0.0f;  verticesData2[2].pos.z =  0.0f;

	//verticesData2[0].color.x =  1.0f;  verticesData2[0].color.y =  0.0f;  verticesData2[0].color.z =  0.0f, verticesData2[0].color.w = 1.0f;
	//verticesData2[1].color.x =  0.0f;  verticesData2[1].color.y =  1.0f;  verticesData2[1].color.z =  0.0f, verticesData2[1].color.w = 0.5f;
	//verticesData2[2].color.x =  0.0f;  verticesData2[2].color.y =  0.0f;  verticesData2[2].color.z =  1.0f, verticesData2[2].color.w = 0.5f;
	//
	//// line data
	//verticesData3 = cameraRay.vertices;
	////triangle2 data (heap)
	//verticesData3[0].pos.x =  0.75f;  verticesData3[0].pos.y =  0.55f;  verticesData3[0].pos.z =  0.15f;
	//verticesData3[1].pos.x = -0.3f;  verticesData3[1].pos.y = -0.15f;  verticesData3[1].pos.z =  0.25f;
	//verticesData3[0].color.x =  1.0f;  verticesData3[0].color.y =  0.0f;  verticesData3[0].color.z =  0.0f, verticesData3[0].color.w = 1.0f;
	//verticesData3[1].color.x =  0.0f;  verticesData3[1].color.y =  1.0f;  verticesData3[1].color.z =  0.0f, verticesData3[1].color.w = 0.5f;
	//
	
	//buffer object
	glGenBuffers(1, &vboId);
	//creation of shaders and program
	return myShaders.Init("../Resources/Shaders/TriangleShaderVS.vs", "../Resources/Shaders/TriangleShaderFS.fs");

}

void Draw ( ESContext *esContext )
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	glUseProgram(myShaders.program);

	glBindBuffer(GL_ARRAY_BUFFER, vboId);
	//triangle.Draw(esContext, &myShaders, &camera);
	//triangle2.Draw(esContext, &myShaders, &camera);
	//cameraRay.Draw(esContext, &myShaders, &camera);
	cube->Draw(esContext, &myShaders, &camera);

	
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
}

void Update ( ESContext *esContext, float deltaTime )
{

}

void Key ( ESContext *esContext, unsigned char key, bool bIsPressed)
{
	if (bIsPressed)
	{
		switch (key)
		{

	/*	case 'W':
			triangle.moveForward();break;
		case 'S':
			triangle.moveBackward();break;
		case 'A':
			triangle.moveLeft();break;
		case 'D':
			triangle.moveRight();break;
		case 'J':
			triangle.RotateLeft();break;
		case 'L':
			triangle.RotateRight();break;
		case 'I':
			triangle.RotateUp();break;
		case 'K':
			triangle.RotateDown();break;*/

		case 'W':
			camera.moveForward();break;
		case 'S':
			camera.moveBackward();break;
		case 'A':
			camera.moveLeft();break;
		case 'D':
			camera.moveRight();break;
		case 'J':
			camera.RotateLeft();break;
		case 'L':
			camera.RotateRight();break;
		case 'I':
			camera.RotateUp();break;
		case 'K':
			camera.RotateDown();break;
			
		case 37:
			cube->RotateLeft();break;
		case 39:
			cube->RotateRight();break;
		case 38:
			cube->RotateUp();break;
		case 40:
			cube->RotateDown();break;
		default: exit(0); break;
		}
	}
}

void CleanUp()
{
	glDeleteBuffers(1, &vboId);
	delete cube;
}

int _tmain(int argc, _TCHAR* argv[])
{
	//identifying memory leaks
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

	ESContext esContext;

    esInitContext ( &esContext );

	esCreateWindow ( &esContext, "Hello Triangle", Globals::screenWidth, Globals::screenHeight, ES_WINDOW_RGB | ES_WINDOW_DEPTH);

	if ( Init ( &esContext ) != 0 )
		return 0;

	esRegisterDrawFunc ( &esContext, Draw );
	esRegisterUpdateFunc ( &esContext, Update );
	esRegisterKeyFunc ( &esContext, Key);

	esMainLoop ( &esContext );

	//releasing OpenGL resources
	CleanUp();

	printf("Press any key...\n");
	_getch();

	return 0;
}

